package com.zhang.authoritycenter.service.impl;

import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhang.authoritycenter.common.model.dao.authority.AuthorityUserOrganizationRelateDO;
import com.zhang.authoritycenter.common.model.dao.organization.OrganizationDO;
import com.zhang.authoritycenter.common.model.dto.organization.OrganizationAddReqDTO;
import com.zhang.authoritycenter.common.model.dto.organization.OrganizationGetListReqDTO;
import com.zhang.authoritycenter.common.model.dto.organization.OrganizationUpdateReqDTO;
import com.zhang.authoritycenter.common.model.serviceimpl.AuthorityUserOrganizationRelateServiceImpl;
import com.zhang.authoritycenter.common.util.UserUtil;
import com.zhang.authoritycenter.dao.organization.OrganizationMapper;
import com.zhang.authoritycenter.service.IOrganizationService;
import com.zhang.infrastructure.model.KingHoodExceptionUtil;
import com.zhang.infrastructure.model.constant.CommonConstants;
import com.zhang.infrastructure.util.base.IdGenUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author KingHood
 * @since 2023-12-18
 */
@RequiredArgsConstructor
@Transactional(rollbackFor = Exception.class)
@Slf4j
@Service
public class OrganizationServiceImpl extends ServiceImpl<OrganizationMapper, OrganizationDO> implements IOrganizationService {

    private final AuthorityUserOrganizationRelateServiceImpl userOrganizationRelateService;

    @Override
    public OrganizationDO addOrganization(OrganizationAddReqDTO in) {
        long count = new LambdaQueryChainWrapper<>(this.getBaseMapper())
                .eq(OrganizationDO::getIsDelete, CommonConstants.IS_DELETE_N)
                .eq(OrganizationDO::getCode, in.getCode())
                .count();
        KingHoodExceptionUtil.trueThrows(count > 0, "组织code已经存在");

        String idPath = null;
        if (Objects.nonNull(in.getParentId())) {
            OrganizationDO parent = getOrganizationInfo(in.getParentId());
            KingHoodExceptionUtil.isNull(parent, "父类不存在");
            idPath = parent.getIdPath();
            KingHoodExceptionUtil.isNull(idPath, "父类idPath存在异常");
        }

        OrganizationDO one = new OrganizationDO();
        BeanUtils.copyProperties(in, one);
        Date now = new Date();
        one.setCreateTime(now);
        one.setUpdateTime(now);
        one.setCreateUserId(UserUtil.getUserId());
        one.setUpdateUserId(UserUtil.getUserId());
        one.setId(IdGenUtil.get().nextId());
        if (idPath == null) {
            one.setIdPath(one.getId().toString());
        } else {
            one.setIdPath(idPath + "/" + one.getId().toString());
        }
        this.save(one);

        log.info("新增api：{}，操作人：{}", in, UserUtil.getUser());
        return one;
    }

    @Override
    public OrganizationDO getOrganizationInfo(Long id) {
        return this.getById(id);
    }

    @Override
    public OrganizationDO updateOrganization(OrganizationUpdateReqDTO in) {
        OrganizationDO one = getOrganizationInfo(in.getId());
        KingHoodExceptionUtil.isNull(one, "api不存在");

        if(Objects.equals(in.getStatus(),CommonConstants.DISABLE)){
            long hasSun = new LambdaQueryChainWrapper<>(this.getBaseMapper())
                    .eq(OrganizationDO::getParentId, in.getId())
                    .eq(OrganizationDO::getStatus, CommonConstants.ENABLE)
                    .eq(OrganizationDO::getIsDelete, CommonConstants.IS_DELETE_N)
                    .count();
            KingHoodExceptionUtil.trueThrows(hasSun > 0, "存在启用状态的下级组织，不允许停用");
        }
        if(Objects.equals(in.getStatus(),CommonConstants.ENABLE) && Objects.nonNull(one.getParentId())){
            long hasParent = new LambdaQueryChainWrapper<>(this.getBaseMapper())
                    .eq(OrganizationDO::getId, one.getParentId())
                    .eq(OrganizationDO::getStatus, CommonConstants.DISABLE)
                    .eq(OrganizationDO::getIsDelete, CommonConstants.IS_DELETE_N)
                    .count();
            KingHoodExceptionUtil.trueThrows(hasParent > 0, "父组织停用状态，请修改父菜单状态");
        }


        String idPath = null;
        if (Objects.nonNull(in.getParentId())) {
            OrganizationDO parent = getOrganizationInfo(in.getParentId());
            KingHoodExceptionUtil.isNull(parent, "父类不存在");
            idPath = parent.getIdPath();
            KingHoodExceptionUtil.isNull(idPath, "父类idPath存在异常");
        }

        BeanUtils.copyProperties(in, one);
        one.setUpdateTime(new Date());
        one.setUpdateUserId(UserUtil.getUserId());
        if (idPath == null) {
            one.setIdPath(one.getId().toString());
        } else {
            one.setIdPath(idPath + "/" + one.getId().toString());
        }
        this.updateById(one);

        log.info("修改组织：{}，操作人：{}", in, UserUtil.getUser());
        return one;
    }

    @Override
    public Boolean deleteOrganizationBatch(List<Long> idList) {
        KingHoodExceptionUtil.isEmpty(idList, "请选择要删除的组织");

        long enableCount = new LambdaQueryChainWrapper<>(this.getBaseMapper())
                .in(OrganizationDO::getId, idList)
                .eq(OrganizationDO::getStatus, CommonConstants.ENABLE)
                .eq(OrganizationDO::getIsDelete, CommonConstants.IS_DELETE_N)
                .count();
        KingHoodExceptionUtil.trueThrows(enableCount > 0, "启用状态不允许删除");

        long hasSun = new LambdaQueryChainWrapper<>(this.getBaseMapper())
                .in(OrganizationDO::getParentId, idList)
                .eq(OrganizationDO::getStatus, CommonConstants.ENABLE)
                .eq(OrganizationDO::getIsDelete, CommonConstants.IS_DELETE_N)
                .count();
        KingHoodExceptionUtil.trueThrows(hasSun > 0, "存在下级组织不允许删除");

        long count = new LambdaQueryChainWrapper<>(userOrganizationRelateService.getBaseMapper())
                .in(AuthorityUserOrganizationRelateDO::getUserId, idList)
                .eq(AuthorityUserOrganizationRelateDO::getIsDelete, CommonConstants.IS_DELETE_N)
                .count();
        KingHoodExceptionUtil.trueThrows(count > 0, "组织存在用户绑定，无法删除");

        boolean update = new LambdaUpdateChainWrapper<>(this.getBaseMapper())
                .in(OrganizationDO::getId, idList)
                .set(OrganizationDO::getIsDelete, CommonConstants.IS_DELETE_Y)
                .set(OrganizationDO::getUpdateUserId, UserUtil.getUserId())
                .set(OrganizationDO::getUpdateTime, new Date())
                .update();

        log.info("删除组织：{}，结果：{}，操作人：{}", idList, update, UserUtil.getUser());
        return update;

    }

    @Override
    public List<OrganizationDO> getList(OrganizationGetListReqDTO in) {

        return new LambdaQueryChainWrapper<>(this.getBaseMapper())
                .eq(StringUtils.isNotBlank(in.getName()), OrganizationDO::getName, in.getName())
                .eq(OrganizationDO::getIsDelete, CommonConstants.IS_DELETE_N)
                .eq(Objects.nonNull(in.getStatus()), OrganizationDO::getStatus, in.getStatus())
                .orderByAsc(OrganizationDO::getParentId)
                .orderByAsc(OrganizationDO::getSort)
                .list();
    }
}
